package cn.dalgen.mybatis.gen.utils.db;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import cn.dalgen.mybatis.gen.model.db.DataBase;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

/**
 * Hikaricp数据库连接池工具类的设计
 *
 * @author Mryang
 */
public class HikaricpUtils {

    // 定义HikariDataSource类型的dataSource
    // 注意： 因为HikariDataSource类 实现了DataSource 接口。 因此 dataSource 即是HikariDataSource类型也是DataSource类型
    private static HikariDataSource dataSource;

    /**
     * 获取数据源
     *
     * @param currentDb
     * @return
     * @throws SQLException
     * @throws IOException
     */
    public static DataSource getDataSource(DataBase currentDb) {
        return getDataSource(currentDb.getDriverClass(), currentDb.getPropertyMapVal("url"),
            currentDb.getPropertyMapVal("userid"), currentDb.getPropertyMapVal("password"));
    }

    /**
     * 获取数据源
     *
     * @return
     * @throws SQLException
     * @throws IOException
     */
    private static DataSource getDataSource(String driverClassName, String jdbcUrl, String username, String password) {
        // 因为dataSource是全局变量、默认初始化值为null
        if (dataSource == null) {
            // 通过字节输入流 读取 配置文件  hikaricp.properties
            Properties props = new Properties();
            props.put("maximumPoolSize", 30);
            props.put("minimumIdle", 30);
            props.put("autoCommit", true);
            props.put("validationTimeout", 3000);
            props.put("idleTimeout", 60000);
            props.put("dataSource.cachePrepStmts", true);
            props.put("dataSource.prepStmtCacheSize", 250);
            props.put("dataSource.prepStmtCacheSqlLimit", 2048);
            props.put("driverClassName", driverClassName);
            props.put("jdbcUrl", jdbcUrl);
            props.put("username", username);
            props.put("password", password);
            // 再将封装好的props 传入到HikariConfig 类中，得到 config对象
            HikariConfig config = new HikariConfig(props);
            // 将config对象传入给HikariDataSource ，返回dataSource
            dataSource = new HikariDataSource(config);
        }
        // 返回dataSource
        return dataSource;
    }

    /**
     * 通过数据源获取连接
     *
     * @return
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

    public static void close() {
        if (dataSource != null) {
            dataSource.close();
            dataSource=null;
        }
    }
}